home *** CD-ROM | disk | FTP | other *** search
/ Linux Cubed Series 7: Sunsite / Linux Cubed Series 7 - Sunsite Vol 1.iso / system / emulator / bsvc-1.000 / bsvc-1 / bsvc-1.0.4 / src / Assemblers / 68kasm / assemble.c < prev    next >
C/C++ Source or Header  |  1995-07-26  |  7KB  |  237 lines

  1. /******************************************************************************
  2.  * $Id: assemble.c,v 1.1 1994/08/29 23:53:27 bmott Exp $
  3.  ******************************************************************************
  4.  *
  5.  *        ASSEMBLE.C
  6.  *        Assembly Routines for 68000 Assembler
  7.  *
  8.  *    Function: processFile()
  9.  *        Assembles the input file. For each pass, the function
  10.  *        passes each line of the input file to assemble() to be 
  11.  *        assembled. The routine also makes sure that errors are 
  12.  *        printed on the screen and listed in the listing file 
  13.  *        and keeps track of the error counts and the line 
  14.  *        number.
  15.  *
  16.  *        assemble()
  17.  *        Assembles one line of assembly code. The line argument
  18.  *        points to the line to be assembled, and the errorPtr 
  19.  *        argument is used to return an error code via the 
  20.  *        standard mechanism. The routine first determines if the
  21.  *        line contains a label and saves the label for later
  22.  *        use. It then calls instLookup() to look up the
  23.  *        instruction (or directive) in the instruction table. If
  24.  *        this search is successful and the parseFlag for that
  25.  *        instruction is TRUE, it defines the label and parses
  26.  *        the source and destination operands of the instruction
  27.  *        (if appropriate) and searches the flavor list for the
  28.  *        instruction, calling the proper routine if a match is
  29.  *        found. If parseFlag is FALSE, it passes pointers to the
  30.  *        label and operands to the specified routine for
  31.  *        processing. 
  32.  *
  33.  *     Usage: processFile()
  34.  *
  35.  *        assemble(line, errorPtr)
  36.  *        char *line;
  37.  *        int *errorPtr;
  38.  *
  39.  *      Author: Paul McKee
  40.  *        ECE492    North Carolina State University
  41.  *
  42.  *        Date:    12/13/86
  43.  *
  44.  *   Copyright 1990-1991 North Carolina State University. All Rights Reserved.
  45.  *
  46.  ******************************************************************************
  47.  * $Log: assemble.c,v $
  48.  * Revision 1.1  1994/08/29  23:53:27  bmott
  49.  * Initial revision
  50.  *
  51.  *****************************************************************************/
  52.  
  53. #include <stdio.h>
  54. #include <ctype.h>
  55. #include "asm.h"
  56.  
  57.  
  58. extern int loc;            /* The assembler's location counter */
  59. extern char pass2;        /* Flag set during second pass */
  60. extern char endFlag;        /* Flag set when the END directive is encountered */
  61. extern char continuation;    /* TRUE if the listing line is a continuation */
  62. extern int lineNum;
  63. extern int errorCount, warningCount;
  64.  
  65. extern char line[256];        /* Source line */
  66. extern FILE *inFile;        /* Input file */
  67. extern FILE *listFile;        /* Listing file */
  68. extern char listFlag;
  69.  
  70.  
  71. processFile()
  72. {
  73. char capLine[256];
  74. int error;
  75. char pass;
  76.  
  77.     pass2 = FALSE;
  78.     for (pass = 0; pass < 2; pass++) {
  79.         loc = 0;
  80.         lineNum = 1;
  81.         endFlag = FALSE;
  82.         errorCount = warningCount = 0;
  83.         while(!endFlag && fgets(line, 256, inFile)) {
  84.             strcap(capLine, line);
  85.             error = OK;
  86.             continuation = FALSE;
  87.             if (pass2 && listFlag)
  88.                 listLoc();
  89.             assemble(capLine, &error);
  90.             if (pass2) {
  91.                 if (error > MINOR)
  92.                     errorCount++;
  93.                 else if (error > WARNING)
  94.                     warningCount++;
  95.                 if (listFlag) {
  96.                     listLine(line, lineNum);
  97.                     printError(listFile, error, -1);
  98.                     }
  99.                 printError(stderr, error, lineNum);
  100.                 }
  101.             lineNum++;
  102.             }
  103.         if (!pass2) {
  104.             pass2 = TRUE;
  105. /*            puts("************************************************************");
  106.             puts("********************  STARTING PASS 2  *********************");
  107.             puts("************************************************************"); */
  108.             }
  109.         rewind(inFile);
  110.         }
  111. }
  112.  
  113.  
  114. assemble(line, errorPtr)
  115. char *line;
  116. int *errorPtr;
  117. {
  118. symbolDef *define();
  119. instruction *tablePtr;
  120. flavor *flavorPtr;
  121. opDescriptor source, dest;
  122. char *p, *start, label[SIGCHARS+1], size, f, sourceParsed, destParsed;
  123. char *skipSpace(), *instLookup(), *opParse();
  124. unsigned short mask, i;
  125.  
  126.     p = start = skipSpace(line);
  127.     if (*p && *p != '*') {
  128.         i = 0;
  129.         do {
  130.             if (i < SIGCHARS)
  131.                 label[i++] = *p;
  132.             p++;
  133.         } while (isalnum(*p) || *p == '.' || *p == '_' || *p == '$');
  134.         label[i] = '\0';
  135.         if ((isspace(*p) && start == line) || *p == ':') {
  136.             if (*p == ':')
  137.                 p++;
  138.             p = skipSpace(p);
  139.             if (*p == '*' || !*p) {
  140.                 define(label, loc, pass2, errorPtr);
  141.                 return;
  142.                 }
  143.             }
  144.         else {
  145.             p = start;
  146.             label[0] = '\0';
  147.             }
  148.         p = instLookup(p, &tablePtr, &size, errorPtr);
  149.         if (*errorPtr > SEVERE)
  150.             return;
  151.         p = skipSpace(p);
  152.         if (tablePtr->parseFlag) {
  153.             /* Move location counter to a word boundary and fix
  154.                the listing before assembling an instruction */
  155.             if (loc & 1) {
  156.                 loc++;
  157.                 listLoc();
  158.                 }
  159.             if (*label)
  160.                 define(label, loc, pass2, errorPtr);
  161.             if (*errorPtr > SEVERE)
  162.                 return;
  163.             sourceParsed = destParsed = FALSE;
  164.             flavorPtr = tablePtr->flavorPtr;
  165.             for (f = 0; (f < tablePtr->flavorCount); f++, flavorPtr++) {
  166.                 if (!sourceParsed && flavorPtr->source) {
  167.                     p = opParse(p, &source, errorPtr);
  168.                     if (*errorPtr > SEVERE)
  169.                         return;
  170. /*                    printOp(&source, "source"); */
  171.                     sourceParsed = TRUE;
  172.                     }
  173.                 if (!destParsed && flavorPtr->dest) {
  174.                     if (*p != ',') {
  175.                         NEWERROR(*errorPtr, SYNTAX);
  176.                         return;
  177.                         }
  178.                     p = opParse(p+1, &dest, errorPtr);
  179.                     if (*errorPtr > SEVERE)
  180.                         return;
  181.                     if (!isspace(*p) && *p) {
  182.                         NEWERROR(*errorPtr, SYNTAX);
  183.                         return;
  184.                         }
  185. /*                    printOp(&dest, "destination"); */
  186.                     destParsed = TRUE;
  187.                     }
  188.                 if (!flavorPtr->source) {
  189. /*                    puts("Zero-operand instruction found"); */
  190.                     mask = pickMask(size, flavorPtr, errorPtr);
  191.                     (*flavorPtr->exec)(mask, errorPtr);
  192.                     return;
  193.                     }
  194.                 else if ((source.mode & flavorPtr->source) && !flavorPtr->dest) {
  195. /*                    puts("One operand instruction found"); */
  196.                     if (!isspace(*p) && *p) {
  197.                         NEWERROR(*errorPtr, SYNTAX);
  198.                         return;
  199.                         }
  200.                     mask = pickMask(size, flavorPtr, errorPtr);
  201.                     (*flavorPtr->exec)(mask, size, &source, &dest, errorPtr);
  202.                     return;
  203.                     }
  204.                 else if (source.mode & flavorPtr->source
  205.                      && dest.mode & flavorPtr->dest) {
  206. /*                    puts("Two operand instruction found"); */
  207.                     mask = pickMask(size, flavorPtr, errorPtr);
  208.                     (*flavorPtr->exec)(mask, size, &source, &dest, errorPtr);
  209.                     return;
  210.                     }
  211.                 }
  212.             NEWERROR(*errorPtr, INV_ADDR_MODE);
  213.             }
  214.         else {
  215.             (*tablePtr->exec)(size, label, p, errorPtr);
  216.             return;
  217.             }
  218.         }
  219. }
  220.  
  221.  
  222. int pickMask(size, flavorPtr, errorPtr)
  223. int size;
  224. flavor *flavorPtr;
  225. int *errorPtr;
  226. {
  227.     if (!size || size & flavorPtr->sizes)
  228.         if (size & (BYTE | SHORT))
  229.             return flavorPtr->bytemask;
  230.         else if (!size || size == WORD)
  231.             return flavorPtr->wordmask;
  232.         else
  233.             return flavorPtr->longmask;
  234.     NEWERROR(*errorPtr, INV_SIZE_CODE);
  235.     return flavorPtr->wordmask;
  236. }
  237.